package util
{
	import flash.utils.ByteArray;
	
	import data.Multiname;
	import data.Trait;
	
	import kinds.TraitAttrKind;
	import kinds.TraitKind;
	
	import tag.doABC2.CPool;

	public class TraitUtil
	{
		public static function trait(bytes:ByteArray, cp:CPool):Trait
		{
			var ret:Trait = new Trait();
			ret.name = (cp.cp_multiname[BytesUtil.readU30(bytes)] as Multiname).toString();
			ret.kind = bytes.readUnsignedByte();
			switch(ret.kind & 0x0F){
				case TraitKind.Trait_Slot:
				case TraitKind.Trait_Const:
					ret.datas = tSlot(bytes, cp);
					break;
				case TraitKind.Trait_Class:
					ret.datas = tClass(bytes);
					break;
				case TraitKind.Trait_Function:
					ret.datas = tFunction(bytes);
					break;
				case TraitKind.Trait_Method:
				case TraitKind.Trait_Setter:
				case TraitKind.Trait_Getter:
					trace(ret.kind & 0x0F);
					ret.datas = tMethod(bytes);
					break;
			}
			
			if(((ret.kind >> 4) & TraitAttrKind.ATTR_Metadata) == TraitAttrKind.ATTR_Metadata){
				var length:uint = BytesUtil.readU30(bytes);
				for (var k:int = 0; k < length; k++){
					ret.metadatas[k] = App.abcFile.metadataArr[BytesUtil.readU30(bytes)];
				}
			}
			
			return ret;
		}
		
		private static function tSlot(bytes:ByteArray, cp:CPool):Object
		{
			var slot_id:uint = BytesUtil.readU30(bytes);
			var index:uint = BytesUtil.readU30(bytes);
			var type_name:String = (cp.cp_multiname[index] as Multiname).toString();
			var vindex:uint = BytesUtil.readU30(bytes);
			var value:String = "";
			var vkind:uint = 0;
			if(vindex > 0){
				vkind = BytesUtil.readU30(bytes);
				value = CPoolUtils.optionValue(cp, vkind, vindex);
			}
			return {slot_id:slot_id, type_name:type_name, vindex:vindex, vkind:vkind, value:value};
		}
		
		private static function tClass(bytes:ByteArray):Object
		{
			return {
				slot_id:BytesUtil.readU30(bytes),
					classi:BytesUtil.readU30(bytes)
			};
		}
		
		private static function tFunction(bytes:ByteArray):Object
		{
			return {
				slot_id:BytesUtil.readU30(bytes),
					functioni:BytesUtil.readU30(bytes)
			};
		}
		
		private static function tMethod(bytes:ByteArray):Object
		{
			return{
				slot_id:BytesUtil.readU30(bytes),
					method:BytesUtil.readU30(bytes)
			}
		}
	}
}